<?php

namespace App\Repositories;


use App\Enums\UserEnum;
use App\Response\Response;
use App\Enums\RedisKeyEnum;
use App\Exceptions\BasicException;
use Illuminate\Support\Facades\DB;
use App\Services\Tools\PushService;
use App\Services\Tools\RedisService;
use App\Services\Tools\RongCloudService;

class FamilyRepository
{
    /**
     * @Desc:列表数据
     * @param $params
     * @param $page
     * @param $pageSize
     * @return mixed
     * @author: shiquan
     * @Time: 2022/11/28 15:40
     */
    public function list($params, $page, $pageSize)
    {
        $familyQuery = app('model_family');
        $users = app('model_user_data');
        $familyQuery = $familyQuery->setTable('t1')->from("ln_family as t1")
            ->select([
                't1.*',
                't2.nickname',
                't2.user_code',
                't2.user_id',
            ])->with('classify')->leftJoin(DB::raw($users->getTable() . " as t2"), "t1.user_id", "=", "t2.user_id");
        if (isset($params['start_time']) && isset($params['end_time'])){
            $params['start_time'] = date('Y-m-d H:i:s', $params['start_time']);
            $params['end_time'] = date('Y-m-d H:i:s', $params['end_time']);
            $familyQuery->whereBetween('t1.created_at', [$params['start_time'], $params['end_time']]);
        }

        if (isset($params['code'])){
            $familyQuery->where('t1.code', $params['code']);
        }

        if (isset($params['id'])){
            $familyQuery->where('t1.id', $params['id']);
        }

        if (isset($params['nickname'])){
            $familyQuery->where('t2.nickname', 'like', '%'.$params['nickname'].'%');
        }

        if (isset($params['user_code'])){
            $familyQuery->where('t2.user_code', $params['user_code']);
        }

        if (isset($params['user_name'])){
            $familyQuery->where('t1.user_name', $params['user_name']);
        }

        if (isset($params['user_id_number'])){
            $familyQuery->where('t1.user_id_number', $params['user_id_number']);
        }
        if (isset($params['name'])){
            $familyQuery->where('t1.name', 'like', '%'.$params['name'].'%');
        }
        $list = $familyQuery->orderBy('t1.id', 'desc')->paginate($pageSize, ['*'], '', $page);

        $familyIds = array_column($list->toArray()['data'], 'id');
        $familyCountArray = app('model_family_user')->whereIn('family_id', $familyIds)->selectRaw('family_id, count(family_id) as count')->groupBy('family_id')->pluck('count', 'family_id')->toArray();
        //新加不合理需求,用户有/check/id_number路由的权限才展示
        $checkPermission = $this->checkPermission('family/check/id_number', $params['role_id']);
        foreach ($list as $key => $item){
            $item['join_num'] = $familyCountArray[$item['id']] ?? 0;
            $item['person_num'] = $item['classify']['person_num'];
            $item['deputy_num'] = $item['classify']['deputy_num'];
            $item['manager'] = $item['classify']['manager'];
            $item['is_permission'] = $checkPermission;    //0=没有权限;1=有权限
            unset($item['classify']);
        }
        return $list;
    }

    /**
     * @Desc:检查是否有某个接口的权限
     * @param $url
     * @param $roleId
     * @return int
     * @author: shiquan
     * @Time: 2022/11/29 11:21
     */
    public function checkPermission($url, $roleId)
    {
        //权限验证，role_id=0表示超级管理员，>0为其它管理员
        if ($roleId > 0) {
            $roleRoutes = app('repo_access')->getRoleAccessRoutes($roleId);
            foreach ($roleRoutes as $route) {
                if ($route['uri'] == $url) {
                    return 1;
                }
            }
            return 0;
        }
        return 1;
    }

    /**
     * @Desc:用户详情--展示
     * @param $params
     * @return mixed
     * @throws BasicException
     * @author: shiquan
     * @Time: 2022/11/28 16:07
     */
    public function info($params)
    {
        $familyInfo = app('model_family')->where('id', $params['id'])->first();
        if (empty($familyInfo)){
            throw new BasicException(100089);
        }
        $userInfo = RedisService::getUserBaseInfo($familyInfo['user_id']);
        $familyInfo['mobile'] = app('model_user')->where('user_id', $familyInfo['user_id'])->value('mobile');
        $familyInfo['nickname'] = $userInfo['nickname'] ?? '';
        $familyInfo['head_picture'] = $userInfo['head_picture'] ?? '';
        $familyInfo['user_code'] = $userInfo['user_code'] ?? '';
        $familyInfo['statistics'] = app('model_family_statistics')->where('family_id', $params['id'])->sum('statistics');
        //新加不合理需求,用户有/check/id_number路由的权限才展示
        $familyInfo['is_permission'] = $this->checkPermission('family/check/id_number', $params['role_id']);
        $familyInfo['join_num'] = app('model_family_user')->where('family_id', $params['id'])->count();
        return $familyInfo;
    }

    /**
     * @Desc:创建初始化家族
     * @param $params
     * @return bool
     * @throws BasicException
     * @author: shiquan
     * @Time: 2022/11/28 16:50
     */
    public function create($params)
    {
        $info = $this->userInfo($params);
        if (empty($info['user_id'])){
            throw new BasicException(100088);
        }

        if ($info['app_status'] == 0 || $info['app_status'] == 2){
            throw new BasicException(100087);
        }
        if ($info['app_status'] == 3){
            throw new BasicException(100080);
        }
        if (app('model_user')->where('user_id', $info['user_id'])->where('seal_time', '>', 0)->first()){
            throw new BasicException(100081);
        }
        //判断这个身份证号是否已经加入家族
        $userIds = app('model_user_auth')->where(['id_number' => $info['user_id_number'], 'app_status' => 1])->pluck('user_id')->toArray();
        if (app('model_family_user')->whereIn('user_id', $userIds)->first()) {
            throw new BasicException(100075);
        }

        if (!app('model_family_classify')->where('id', $params['classify_id'])->first()){
            throw new BasicException(100086);
        }

        $data = [
            'user_id' => $info['user_id'],
            'classify_id' => $params['classify_id'],
            'user_name' => $info['user_name'],
            'user_id_number' => $info['user_id_number'],
            'status' => 0,
            'code' => $this->code(),
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ];
        \DB::beginTransaction();
        try {
            $familyId = app('model_family')->insertGetId($data);
            app('model_family_user')->create([
                'family_id' => $familyId,
                'user_id' => $info['user_id'],
                'role' => UserEnum::SHAIKH,
            ]);
            app('model_family_user_change_log')->create([
                'family_id' => $familyId,
                'user_id' => $info['user_id'],
                'type' => 1,
                'source_id' => $familyId,
                'created_at' => date('Y-m-d H:i:s'),
            ]);
            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            throw new BasicException(100085);
        }

        return true;
    }

    /**
     * @Desc:用户信息
     * @param $params
     * @return array
     * @author: shiquan
     * @Time: 2022/11/28 16:17
     */
    public function userInfo($params)
    {
        $userCode = $params['user_code'];
        $userId = app('model_user_data')->where('user_code', $userCode)->value('user_id');
        $userAuthInfo = app('model_user_auth')->select('full_name', 'id_number', 'app_status')->where(['user_id' => $userId])->where('app_status', '<', 4)->orderBy('id', 'desc')->first();
        $userInfo = RedisService::getUserBaseInfo($userId);
        $info['user_id'] = $userId;
        $info['nickname'] = $userInfo['nickname'] ?? '';
        $info['head_picture'] = $userInfo['head_picture'] ?? '';
        $info['user_name'] = $userAuthInfo['full_name'] ?? '';
        $info['user_id_number'] = $userAuthInfo['id_number'] ?? '';
        $info['app_status'] = $userAuthInfo['app_status'] ?? 0;
        $info['user_code'] = $userCode;
        $info['mobile'] = app('model_user')->where('user_id', $userId)->value('mobile');
        //新加不合理需求,用户有/check/id_number路由的权限才展示
        if (!empty($params['role_id'])){
            $info['is_permission'] = $this->checkPermission('family/check/id_number', $params['role_id']);
        }
        return $info;
    }

    /**
     * @Desc:家族规模
     * @return mixed
     * @author: shiquan
     * @Time: 2022/11/28 16:18
     */
    public function familyClassify()
    {
        return app('model_family_classify')->get()->toArray();
    }

    /**
     * @Desc:家族编号
     * @return int
     * @author: shiquan
     * @Time: 2022/11/28 16:59
     */
    public function code()
    {
        $code = mt_rand(1001000, 9999999);
        if (app('model_family')->where('code', $code)->value('id')){
            return $this->code();
        }
        return $code;
    }

    /**
     * @Desc: 编辑
     * @param $params
     * @return bool
     * @throws BasicException
     * @author: shiquan
     * @Time: 2022/11/28 17:53
     */
    public function update($params)
    {
        $familyInfo = app('model_family')->where('id', $params['id'])->first();
        $data = [];
        if (isset($params['icon'])){
            $data['icon'] = $params['icon'];
        }
        if (isset($params['name'])){
            $data['name'] = $params['name'];
        }
        if (isset($params['classify_id'])){
            if (!$classify = app('model_family_classify')->where('id', $params['classify_id'])->first()){
                throw new BasicException(100086);
            }
            //大规模的不能改为小规模--新需求
            $currentPersonNum = app('model_family_classify')->where('id', $familyInfo['classify_id'])->first()['person_num'] ?? 0;
            //判断下当前人数
            //$count = app('model_family_user')->where('family_id', $params['id'])->count();
            if ($classify['person_num'] < $currentPersonNum){
                throw new BasicException(100083);
            }
            $data['classify_id'] = $params['classify_id'];
        }
        $userCode = RedisService::getUserBaseInfo($familyInfo['user_id'])['user_code'] ?? '';
        //现在的用户code和之前的code不一致才进来
        if (isset($params['user_code']) && $params['user_code'] != $userCode){
            throw new BasicException(0,'不能更换族长!');      //更换族长之后

            $info = $this->userInfo($params);
            if (empty($info['user_id'])){
                throw new BasicException(100088);
            }

            if ($info['app_status'] == 0 || $info['app_status'] == 2){
                throw new BasicException(100087);
            }

            if ($info['app_status'] == 3){
                throw new BasicException(100080);
            }

            if (app('model_user')->where('user_id', $info['user_id'])->where('seal_time', '>', 0)->first()){
                throw new BasicException(100081);
            }

            //判断这个身份证号是否已经加入家族
            $userIds = app('model_user_auth')->where(['id_number' => $info['user_id_number'], 'app_status' => 1])->pluck('user_id')->toArray();

            if (app('model_family_user')->whereIn('user_id', $userIds)->first()) {
                throw new BasicException(100075);
            }

            $data['user_id'] = $info['user_id'];
            $data['user_name'] = $info['user_name'];
            $data['user_id_number'] = $info['user_id_number'];
        }

        if (!empty($data)){
            $redisKey = RedisKeyEnum::FAMILY_DETAIL;
            \DB::beginTransaction();
            try {
                app('model_family')->where('id', $params['id'])->update($data);
                if (!empty($data['user_id'])){
                    app('model_family_user')->create([
                        'family_id' => $params['id'],
                        'user_id' => $data['user_id'],
                        'role' => UserEnum::SHAIKH,
                    ]);
                    app('model_family_user_change_log')->create([
                        'family_id' => $params['id'],
                        'user_id' => $data['user_id'],
                        'type' => 1,
                        'source_id' => $params['id'],
                        'created_at' => date('Y-m-d H:i:s'),
                    ]);
                    //将之前的族长删除
                    app('model_family_user')->where(['family_id' => $params['id'], 'user_id' => $familyInfo['user_id']])->delete();

                    app('model_family_user_change_log')->create([
                        'family_id' => $params['id'],
                        'user_id' => $familyInfo['user_id'],
                        'type' => 2,
                        'source_id' => $params['id'],
                        'created_at' => date('Y-m-d H:i:s'),
                    ]);
                }
                DB::commit();
                app('redis')->hdel($redisKey, $params['id']);
            }catch (\Exception $exception){
                DB::rollBack();
                throw new BasicException(100085);
            }
        } else {
            throw new BasicException(100082);
        }
        return true;
    }

    /**
     * @Desc:解散
     * @param $params
     * @throws BasicException
     * @author: shiquan
     * @Time: 2022/11/29 10:27
     */
    public function delete($params)
    {
        $redisKey = RedisKeyEnum::FAMILY_DETAIL;
        $familyInfo = app('model_family')->where('id', $params['id'])->first();
        if (empty($familyInfo)){
            throw new BasicException(100089);
        }
        \DB::beginTransaction();
        try {
            $familyUser = app('model_family_user')->where('family_id', $params['id'])->pluck('user_id')->toArray();
            app('model_family')->where('id', $params['id'])->delete();
            app('model_family_dissolve')->create([
                'family_id' => $params['id'],
                'reason' => '后台手动解散',
                'operator' => $params['admin_id'],
            ]);
            app('model_family_user')->where('family_id', $params['id'])->delete();
            app('model_family_user_apply')->where('family_id', $params['id'])->update([
                'audit_status' => 2,
                'audit_time' => date('Y-m-d H:i:s'),
                'operator' => $params['admin_id']
            ]);
            $this->dissolveRyFamily($params['id'], $familyInfo['user_id']);
            DB::commit();
            app('redis')->hdel($redisKey, $params['id']);
        }catch (\Exception $exception){
            DB::rollBack();
            throw new BasicException(100079);
        }
        //发送系统消息到用户
        if (!empty($familyUser)){
            foreach ($familyUser as $value){
                //1.家族成员发送消息
                app('repo_user_news')->userNewsAdd([
                    'user_id'  => $value,
                    'content'  => '您所在的'.$familyInfo['name'].'家族已解散。',
                    'add_time' => time(),
                    'title'    => '系统消息提示',
                ]);
            }
        }

        if (!empty($familyInfo['ry_family'])){
            //还需要给家族群发送推送
            //推送
            $pushData = [
                'family_id' => $params['id'],
                'message' => '家族已解散',
                'user_id' => $familyInfo['user_id']
            ];
            (new RongCloudService())->pushFamily('user_' . $familyInfo['user_id'], $familyInfo['ry_family'], $pushData, PushService::DISSOLVE_FAMILY);
        }
        return true;
    }

    /**
     * @Desc:解散融云群组
     * @param $familyId
     * @param $userId
     * @return array
     * @throws BasicException
     * @author: shiquan
     * @Time: 2022/12/13 17:53
     */
    public function dissolveRyFamily($familyId, $userId)
    {
        $ryRoomId = (new RongCloudService())->dissolveRyFamily($familyId, $userId);
        if (!$ryRoomId) {
            throw new BasicException(0,'解散群组失败，请联系管理员');
        }
        return $ryRoomId;
    }

    /**
     * @Desc:红包召集记录
     * @param $params
     * @param $page
     * @param $pageSize
     * @return mixed
     * @author: shiquan
     * @Time: 2023/1/31 11:20
     */
    public function redPacketList($params, $page, $pageSize)
    {
        $familyQuery = app('model_family_red_packet');
        $family = app('model_family');
        $familyQuery = $familyQuery->setTable('t1')->from('ln_family_red_packet as t1')
            ->select([
                't1.*',
                't2.name',
                't2.code',
            ])->leftJoin(DB::raw($family->getTable() . ' as t2'), 't1.family_id', '=', 't2.id');
        if (isset($params['start_time']) && isset($params['end_time'])){
            $familyQuery->whereBetween('t1.created_at', [$params['start_time'], $params['end_time']]);
        }

        if (isset($params['room_code'])){
            $familyQuery->where('t1.room_code', $params['room_code']);
        }

        if (isset($params['user_code'])){
            $userId = app('model_user_data')->where('user_code', $params['user_code'])->value('user_id');
            $familyQuery->where('t1.user_id', $userId);
        }

        if (isset($params['status'])){
            $familyQuery->where('t1.status', $params['status']);
        }

        if (isset($params['code'])){
            $familyQuery->where('t2.code', $params['code']);
        }

        $list = $familyQuery->orderBy('t1.id', 'desc')->paginate($pageSize, ['*'], '', $page);

        $userIds = array_column($list->toArray()['data'], 'user_id');
        $userArray = app('model_user_data')->whereIn('user_id', $userIds)->select('nickname', 'user_id', 'user_code')->get()->toArray();
        $userCodes = $userName = [];
        if (!empty($userArray)){
            foreach ($userArray as $value){
                $userCodes[$value['user_id']] = $value['user_code'];
                $userName[$value['user_id']] = $value['nickname'];
            }
        }

        foreach ($list as $item){
            $item['nickname'] = $userName[$item['user_id']] ?? '';
            $item['user_code'] = $userCodes[$item['user_id']] ?? '';
        }
        return $list;
    }

    /**
     * @Desc:召集详情
     * @param $param
     * @param $page
     * @param $pageSize
     * @return array
     * @throws BasicException
     * @author: shiquan
     * @Time: 2023/1/31 11:35
     */
    public function redPacketInfo($param, $page, $pageSize)
    {
        $redPacket = app('model_family_red_packet')->select('number', 'gold', 'status')->where('id', $param['id'])->first();
        if (empty($redPacket)){
            throw new BasicException(100074);
        }
        $redPacketInfo = app('model_family_red_packet_detail')->where('redpacket_id', $param['id'])->selectRaw('count(*) as count, SUM(gold) as gold')->first();
        $redQuery = app('model_family_red_packet_detail');
        $user = app('model_user_data');
        $redPacketList = $redQuery->setTable('t1')->from('ln_family_red_packet_detail as t1')
            ->select([
                't1.id',
                't1.created_at',
                't1.gold',
                't2.nickname',
                't2.user_code',
            ])->leftJoin(DB::raw($user->getTable() . ' as t2'), 't1.user_id', '=', 't2.user_id')
            ->where('t1.redpacket_id', $param['id'])
            ->orderBy('t1.id', 'desc')->paginate($pageSize, ['*'], '', $page);

        $list = json_decode(Response::sendList($redPacketList), true);
        return [
            'data' => [
                'redpacket_has_receive_count' => $redPacketInfo['count'] ?? 0,
                'redpacket_total_receive_count' => $redPacket['number'],
                'redpacket_has_receive_gold' => $redPacketInfo['gold'] ?? 0,
                'redpacket_total_receive_gold' => $redPacket['gold'],
                'status' => $redPacket['status']
            ],
            'list' => $list['data']['list'],
            'meta' => $list['data']['meta'],
        ];
    }
}